Release 10.1A: OpenEdge Development:
Progress 4GL Handbook
REPEAT blocks
There’s a third kind of iterating block that is in between
DOandFORin its effects, theREPEATblock. It supports just about all the same syntax as aFORblock. You can add aFORclause for one or more tables to it. You can use aWHILEphrase or theexpressionTOexpressionphrase. You can scope a frame to it.A block that begins with the
REPEATkeyword shares these default characteristics with aFORblock:By contrast, it shares this important property with a
DOblock: It does not automatically read records as it iterates.So what is a
REPEATblock for? It is useful in cases where you need to process a set of records within a block but you need to navigate through the records yourself, rather than simply proceeding to the next record automatically on each iteration. The sample procedure starting in the "Index cursors" sectionshows you an example of where to use theREPEATblock.One of the common ways to use a
REPEATblock in older character applications is to repeat a data entry action until the user hits the ESCAPE key to end. Here’s a very simple but powerful example:
You haven’t seen the
INSERTstatement before and you won’t see much of it again, even though it’s one of the most powerful statements in the language. Figure 6–14 shows what you get from that one simple statement.Figure 6–14: Results of using the INSERT statement
![]()
It’s a complete data entry screen, complete with initial values for fields that have one. The field help displays at the bottom of the window. Inside a
REPEATloop, this lets you create one new Customer record after another until you’re done and you press ESCAPE.Why won’t you see the
INSERTstatement again? BecauseINSERTis one of those statements that mixes up all aspects of Progress, from the user interface to saving the data off into the database. And in a modern GUI application, you need to separate out all those things into separate parts of your application. You’ll look at database updates in Chapter 16, "Updating Your Database and Writing Triggers," so there’s no need to go into this example any further beyond understanding what theREPEATblock does around the statement.Using the PRESELECT keyword to get data in advance
One typical use of the
REPEATblock that is still valuable is when you use it with a construct called aPRESELECT. To understand this usage, you need to think a little about what happens when an iterating block like aFOR EACHblock begins. Progress evaluates the record retrieval theFOR EACHstatement defines. It then goes out to the database and retrieves the first record of the set of related records that satisfies the statement and makes the record available to the block. When the block iterates, Progress goes and gets the next record. As long as it’s possible to identify what the first and the next records are by using one or more indexes, Progress doesn’t bother reading all the records in advance. It just goes out and gets them when the block needs them.If you specify a
BYclause that requires a search of the database that an index can’t satisfy, Progress has no choice but to retrieve all the records in advance and build up a list in sort order. But this is not ordinarily the case. It’s much more efficient simply to get the records when you need them.Sometimes, though, you need to force Progress to get all the records that satisfy the
FOR EACHstatement in advance, even when the sort order itself doesn’t require it. For example, if it’s possible that you will modify an indexed field in some of the records in such a way that they would appear again later in the retrieval process, you need to make sure that the set of records you’re working with is predetermined. ThePRESELECTkeyword gives you this. It tells Progress to build up a list of pointers to all the records that satisfy the selection criteria before it starts iterating through the block. This assures you that each record is accessed only once.In summary, a
REPEATblock does everything aFORblock does, but it does not automatically advance to the next record as it iterates. You should use aREPEATblock in cases where you want to control the record navigation yourself, typically using theFINDstatement described in the next section. It provides you with record, frame, and transaction scoping.Because it provides all these services, a
REPEATblock is relatively expensive compared to aDOblock. Use the simplerDOblock instead of aREPEATblock, unless you need the record-oriented services provided by theREPEATblock.
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |